package com.pufa.util;

import java.io.File;
import java.io.FileWriter;
import java.util.Iterator;
import java.util.List;


import net.sf.json.JSONObject;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Namespace;
import org.dom4j.Node;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.SAXWriter;
import org.dom4j.io.XMLWriter;
import org.xml.sax.SAXException;

public class Dom4jUtil {

	// private Logger log = Logger.getLogger(Dom4jUtil.class);

	/**
	 * 创建document
	 * 
	 * @return
	 */
	public static Document createDomFJ() {
		Document doc = DocumentHelper.createDocument();
		return doc;
	}

	/**
	 * 给文档添加根节点
	 * 
	 * @param elName
	 *            子节点名称
	 * @param doc
	 *            文档
	 * @return
	 */
	public static Element appendChile(String elName, Document doc) {
		Element root = doc.addElement(elName);
		return root;
	}

	/**
	 * 给父节点添加子节点
	 * 
	 * @param elName
	 *            子节点的名称
	 * @param el
	 *            父节点
	 * @return
	 */
	public static Element appendChile(String elName, Element el) {
		Element sub = el.addElement(elName);
		return sub;
	}
	

	/**
	 * 添加子节点及其对应的值
	 * 
	 * @param elName
	 *            子节点的名称
	 * @param value
	 *            子节点的值
	 * @param el
	 *            父节点
	 */
	public static void appendChile(String elName, String value, Element el) {
		Element sub = el.addElement(elName);
		sub.setText(value);
	}

	/**
	 * 根目录添加注释
	 * 
	 * @param explain
	 *            说明文字
	 * @param doc
	 */
	public static void addCommend(String explain, Document doc) {
		doc.addComment(explain);
	}

	/**
	 * 为子节点添加说明
	 * 
	 * @param explain
	 * @param element
	 */
	public static void addCommend(String explain, Element element) {
		element.addComment(explain);
	}

	/**
	 * 为节点添加属性
	 * 
	 * @param attName
	 * @param attValue
	 * @param element
	 */
	public static void addAttribute(String attName, String attValue,
			Element element) {
		element.addAttribute(attName, attValue);
	}

	/**
	 * 根据XML文件名读取
	 * 
	 * @param url
	 * @param doc
	 * @throws Exception
	 */
	public static Document  readXMLtoDoc(String url) throws Exception {
		Document doc = null;
		File file = new File(url);
		if (file.exists()) {
			SAXReader saxReader = new SAXReader();
			doc = saxReader.read(new File(url));
		}
		return doc;
	}

	/**
	 * 保存到XML文件
	 * @param url
	 * @param doc
	 * @throws Exception
	 */
	public static void writeDoctoXML(String url, Document doc) throws Exception {
		// 指定文件
		XMLWriter writer = new XMLWriter(new FileWriter(url));
		writer.write(doc);
		writer.close();
		// 美化格式
		OutputFormat format = OutputFormat.createPrettyPrint();
		writer = new XMLWriter(System.out, format);
		writer.write(doc);
		// 缩减格式
		format = OutputFormat.createCompactFormat();
		writer = new XMLWriter(System.out, format);
		writer.write(doc);
	}
	/**
	 * 根据路径获取，找不到文件创建新的
	 * @param url
	 * @return
	 * @throws Exception
	 */
	public static Document getOrCreateDoc(String url) throws Exception {
		Document doc = Dom4jUtil.readXMLtoDoc(url);
		if (doc == null) {
			// 创建文档
			doc = Dom4jUtil.createDomFJ();
			// 创建根节点
			Dom4jUtil.appendChile("root", doc);
		}
		return doc;
	}
	/**
	 * 根据名字取得唯一节点
	 * @param name
	 * @param doc
	 * @return
	 */
	public static Node getNodeByName(String name, Document doc){
		return doc.selectSingleNode("//" + name);
	}
	/**
	 * 获取根目录下所有的子元素
	 * @param doc
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static List<Node> getAll(Document doc){
		return doc.selectNodes("/root/*");
	}

	/**
	 * 根据节点名字获取节点下所有元素
	 * @param name
	 * @param doc
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static List<Node> select(String name, Document doc) {
		return doc.selectNodes("/"+name+"/*");
	}
	
	@SuppressWarnings("unchecked")
	public static void delChildByName(String childName, Document doc) {
		 List<Node> list = doc.selectNodes("//" +childName);
		 for (Iterator<Node> iterator = list.iterator(); iterator.hasNext();) {
			Node node = (Node) iterator.next();
			doc.remove(node);
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		String url = System.getProperty("user.dir") + "\\data.xml";
		
		try {
			Document doc = Dom4jUtil.getOrCreateDoc(url);
//			System.out.println(doc.asXML());
//			Element e = Dom4jUtil.appendChile("p10000002", doc.getRootElement());
//			delChildByName("data", doc);
//			Node node = doc.selectSingleNode(//root/bar/author);
//			String name = node.valueOf( @name );
//			System.out.println(e.asXML());
//			Dom4jUtil.addAttribute("10000001", "1000001", e);
//			Dom4jUtil.addAttribute("is", "y", e);
			
			System.out.println(doc.selectSingleNode("//p10000003").getName());
			JSONObject jo = new JSONObject(false);
			System.out.println(jo);
//			List<Node> list = doc.selectNodes("//p10000003");
//			System.out.println(list.size());
//			doc.remove(list.get(0));
//			System.out.println(list.size());
//			doc.remove(Dom4jUtil.getNodeByName("p10000001", doc));
//			Dom4jUtil.writeDoctoXML(url ,doc);
			System.out.println(doc.selectNodes("/root/*").size());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.gc();
	}

}
